Skip to content

Add new lint: manual_slice_match#17232

Open
sylvestre wants to merge 1 commit into
rust-lang:masterfrom
sylvestre:manual_slice_match
Open

Add new lint: manual_slice_match#17232
sylvestre wants to merge 1 commit into
rust-lang:masterfrom
sylvestre:manual_slice_match

Conversation

@sylvestre

Copy link
Copy Markdown
Contributor

Add a new pedantic lint that detects if/else if chains whose conditions only inspect the length/emptiness of one and the same slice or Vec (via .is_empty() or .len() compared against an integer literal) and rewrites them as a match on a slice pattern.

The lint is conservative: it requires at least two conditions over the same receiver and an explicit final else, and rejects chains that mix in value guards. It generates concrete arms ([], [_], [_, _, ..]) where the length predicates are expressible as slice patterns, and falls back to a help-only diagnostic for comparisons that cannot be a single pattern set (<, <=, !=). Arrays are not linted, since their length is a compile-time constant. The suggestion is MaybeIncorrect (bodies are copied verbatim and matching a Vec borrows the receiver across the arms). It is gated on the slice-patterns MSRV (1.42).

changelog: Add new lint: manual_slice_match

@rustbot rustbot added the needs-fcp PRs that add, remove, or rename lints and need an FCP label Jun 13, 2026
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 13, 2026
@rustbot

rustbot commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

r? @samueltardieu

rustbot has assigned @samueltardieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: 8 candidates
  • 8 candidates expanded to 8 candidates
  • Random selection from Jarcho, dswij, llogiq, samueltardieu

@sylvestre
sylvestre force-pushed the manual_slice_match branch 2 times, most recently from 3c13460 to cc357a3 Compare June 13, 2026 21:31
@sylvestre
sylvestre marked this pull request as draft June 13, 2026 21:38
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 13, 2026
@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown

Lintcheck changes for 40edded

Lint Added Removed Changed
clippy::manual_slice_match 5 0 0

This comment will be updated if you push new changes

@sylvestre
sylvestre force-pushed the manual_slice_match branch from cc357a3 to 09edb05 Compare June 13, 2026 21:42
@sylvestre
sylvestre marked this pull request as ready for review June 13, 2026 21:45
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 13, 2026
@rustbot

This comment has been minimized.

@sylvestre
sylvestre force-pushed the manual_slice_match branch from 09edb05 to bc8bc1e Compare June 17, 2026 06:52
@rustbot

This comment has been minimized.

@samueltardieu samueltardieu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following triggers the lint while it shouldn't:

fn slice_len_chain_impure(s: impl Fn() -> &'static [u32]) {
    if s().len() == 0 {
        println!("empty");
    } else if s().len() > 1 {
        println!("{} {}", s()[0], s()[1]);
    } else {
        println!("one");
    }
}

You have to check that the expressions are equal and don't have side-effects.

Also, a limit would be nice, as this one will generate some particularly ugly code:

    if s.is_empty() {
        println!("empty");
    } else if s.len() > 100 {
        println!("large");
    } else {
        println!("small");
    }

View changes since this review

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jun 17, 2026
@rustbot

rustbot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@sylvestre
sylvestre force-pushed the manual_slice_match branch from bc8bc1e to 02c2e93 Compare June 22, 2026 08:39
@rustbot

This comment has been minimized.

@sylvestre

sylvestre commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Lintcheck - 2 hits on default set (27 crates), 4 hits on extended set (499 crates), no ICEs.

@Jarcho

Jarcho commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

You don't need to post lintcheck results. It's run automatically every time you push and the comment (#17232 (comment)) is kept updated with the change from master.

@sylvestre

Copy link
Copy Markdown
Contributor Author

TIL, thanks

@rustbot

This comment has been minimized.

@sylvestre
sylvestre force-pushed the manual_slice_match branch from 02c2e93 to 5a208ee Compare July 6, 2026 22:57
@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot rustbot added the has-merge-commits PR has merge commits, merge with caution. label Jul 11, 2026
Add a new pedantic lint that detects `if`/`else if` chains whose
conditions only inspect the length/emptiness of one and the same slice
or `Vec` (via `.is_empty()` or `.len()` compared against an integer
literal) and rewrites them as a `match` on a slice pattern.

The lint is conservative: it requires at least two conditions over the
same receiver and an explicit final `else`, and rejects chains that mix
in value guards. It generates concrete arms (`[]`, `[_]`, `[_, _, ..]`)
where the length predicates are expressible as slice patterns, and falls
back to a help-only diagnostic for comparisons that cannot be a single
pattern set (`<`, `<=`, `!=`). Arrays are not linted, since their length
is a compile-time constant. The suggestion is `MaybeIncorrect` (bodies
are copied verbatim and matching a `Vec` borrows the receiver across the
arms). It is gated on the slice-patterns MSRV (1.42).
@sylvestre
sylvestre force-pushed the manual_slice_match branch from 40edded to 86359a0 Compare July 11, 2026 21:54
@rustbot

rustbot commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jul 11, 2026
@rustbot

rustbot commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (possibly #17385) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-fcp PRs that add, remove, or rename lints and need an FCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants